package com.kingre.et.action;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.context.SecurityContextHolder;

import com.kingre.et.chart.BarChart;
import com.kingre.et.chart.SpiderChart;
import com.kingre.et.model.DimensioScore;
import com.kingre.et.model.Rawdata;
import com.kingre.et.model.User;
import com.kingre.et.service.IDisReportService;
import com.kingre.et.util.ExportPDF;
import com.kingre.et.util.FormulaUtils;
import com.opensymphony.xwork2.ActionSupport;

public class DisReportAction extends ActionSupport {
    private static final long serialVersionUID = -6549592545776171859L;
    @Autowired
    private IDisReportService disReportService;
    private List<Rawdata> rawdatas;
    private List<DimensioScore> dimensioScores;

    private String dimensioDes;

    /**
     * 职业适应力指数
     */
    private Integer adapScore;
    /**
     * 驱动力指数
     */
    private Integer driveScore;
    /**
     * 保障力指数
     */
    private Integer ensureScore;
    /**
     * 执行力指数
     */
    private Integer executeScore;
    /**
     * 报告真实度
     */
    private Integer flamScore;

    /**
     * 蜘蛛图名称
     */
    private String spiderCharName;

    private String barChartName0;
    private String barChartName1;
    private String barChartName2;
    private String barChartName3;
    private String barChartName4;
    private String barChartName5;
    private String barChartName6;
    private String barChartName7;
    private String barChartName8;
    private Integer id;
    private User user;

    private String filename;

    public String export() {
        return SUCCESS;
    }

    private String groupDimensio(List<DimensioScore> dimensioScores) {
        String des = "在适应力分项指标上，";
        String high = "";
        String middle = "";
        String low = "";
        for (DimensioScore ds : dimensioScores) {
            if (ds.getStandardScore() >= 8)
                high += (high.equals("") ? ds.getDimensionality().getName() : ("、" + ds.getDimensionality().getName()));
            else if (ds.getStandardScore() >= 4)
                middle += (middle.equals("") ? ds.getDimensionality().getName() : ("、" + ds.getDimensionality()
                        .getName()));
            else
                low += (low.equals("") ? ds.getDimensionality().getName() : ("、" + ds.getDimensionality().getName()));
        }
        if (!high.equals("")) {
            des += ("您的" + high + "处于较高水平，是您发展的优势，请继续保持；");
        }
        if (!middle.equals("")) {
            des += ("您的" + middle + "处于中等水平,有提升的空间；");
        }
        if (!low.equals("")) {
            des += (low + "低于人群平均水平，是您适应力中最弱的部分，考虑到整体适应力发展的均衡，需要您在学习和实践中提升这部分的适应力，以弥补不足，促进您的职业发展。");
        }
        return des;
    }

    private void createReportDate() throws IOException {
        Integer uid;
        if (id == null || id == 0) {
            User currentUser = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            uid = currentUser.getId();
        } else {
            uid = id;
        }
        rawdatas = disReportService.getRawdata(uid);
        if (rawdatas != null) {
            barChartName0 = createBarChart(rawdatas, 0);
            barChartName1 = createBarChart(rawdatas, 1);
            barChartName2 = createBarChart(rawdatas, 2);
            barChartName3 = createBarChart(rawdatas, 3);
            barChartName4 = createBarChart(rawdatas, 4);
            barChartName5 = createBarChart(rawdatas, 5);
            barChartName6 = createBarChart(rawdatas, 6);
            barChartName7 = createBarChart(rawdatas, 7);
            barChartName8 = createBarChart(rawdatas, 8);
        }
        dimensioScores = disReportService.getDimensioScore(uid);
        if (dimensioScores != null) {
            spiderCharName = createSpiderChart(dimensioScores);
            adapScore = FormulaUtils.getAVGToInt(dimensioScores.get(0).getStandardScore(), dimensioScores.get(1)
                    .getStandardScore(), dimensioScores.get(2).getStandardScore(), dimensioScores.get(3)
                    .getStandardScore(), dimensioScores.get(4).getStandardScore(), dimensioScores.get(5)
                    .getStandardScore(), dimensioScores.get(6).getStandardScore(), dimensioScores.get(7)
                    .getStandardScore(), dimensioScores.get(8).getStandardScore());
            ensureScore = FormulaUtils.getAVGToInt(dimensioScores.get(0).getStandardScore(), dimensioScores.get(1)
                    .getStandardScore(), dimensioScores.get(2).getStandardScore());
            driveScore = FormulaUtils.getAVGToInt(dimensioScores.get(3).getStandardScore(), dimensioScores.get(4)
                    .getStandardScore(), dimensioScores.get(5).getStandardScore());
            executeScore = FormulaUtils.getAVGToInt(dimensioScores.get(6).getStandardScore(), dimensioScores.get(7)
                    .getStandardScore(), dimensioScores.get(8).getStandardScore());
        }
        flamScore = disReportService.getFlamScore(uid);
        dimensioDes = groupDimensio(dimensioScores);
        user = disReportService.getUser(uid);
    }

    public InputStream getInputStream() throws Exception {
        createReportDate();
        return new ByteArrayInputStream(ExportPDF.getPDFStream(this).toByteArray());

    }

    public String report() throws IOException {
        createReportDate();
        return SUCCESS;
    }

    public String createSpiderChart(List<DimensioScore> dimensioScores) throws IOException {
        CategoryDataset dataset = createDataset(dimensioScores);
        JFreeChart chart = SpiderChart.createChart(dataset);

        StandardEntityCollection entityCollection = new StandardEntityCollection();
        ChartRenderingInfo info = new ChartRenderingInfo(entityCollection);
        return ServletUtilities.saveChartAsPNG(chart, 400, 320, info, null);
    }

    public String createBarChart(List<Rawdata> rawdatas, int index) throws IOException {
        JFreeChart chart = BarChart.generateChart("", "", getText("chart.ylabel"), putChartDataset(rawdatas, index));
        StandardEntityCollection entityCollection = new StandardEntityCollection();
        ChartRenderingInfo info = new ChartRenderingInfo(entityCollection);
        return ServletUtilities.saveChartAsPNG(chart, 500, 200, info, null);
    }

    public CategoryDataset createDataset(List<DimensioScore> dimensioScores) {
        String group1 = "各维度得分";
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (DimensioScore ds : dimensioScores) {
            dataset.addValue(ds.getStandardScore(), group1, ds.getDimensionality().getAlias());
        }
        return dataset;
    }

    private List<Map<String, String>> putChartDataset(List<Rawdata> rawdatas, int index) {
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
        Map<String, String> map;
        if (rawdatas == null)
            return list;
        map = new HashMap<String, String>();
        map.put("vd", getText("chart.vd" + (index * 3)));
        int avg = FormulaUtils.getAVGToInt(rawdatas.get(index * 9).getStandardScore(), rawdatas.get((index * 9) + 1)
                .getStandardScore(), rawdatas.get((index * 9) + 2).getStandardScore());
        map.put("value", String.valueOf(avg));
        list.add(map);
        rawdatas.get((index * 9)).setTypeName(getText("chart.vd" + (index * 3)));
        rawdatas.get((index * 9)).setLevelName(
                avg >= 9 ? "很高" : (avg >= 7 ? "较高" : (avg >= 5 ? "中等" : (avg >= 3 ? "较低" : "很低"))));

        map = new HashMap<String, String>();
        map.put("vd", getText("chart.vd" + (index * 3 + 1)));
        avg = FormulaUtils.getAVGToInt(rawdatas.get((index * 9) + 3).getStandardScore(), rawdatas.get((index * 9) + 4)
                .getStandardScore(), rawdatas.get((index * 9) + 5).getStandardScore());
        map.put("value", String.valueOf(avg));
        list.add(map);
        rawdatas.get((index * 9 + 3)).setTypeName(getText("chart.vd" + (index * 3 + 1)));
        rawdatas.get((index * 9 + 3)).setLevelName(
                avg >= 9 ? "很高" : (avg >= 7 ? "较高" : (avg >= 5 ? "中等" : (avg >= 3 ? "较低" : "很低"))));

        map = new HashMap<String, String>();
        map.put("vd", getText("chart.vd" + (index * 3 + 2)));
        avg = FormulaUtils.getAVGToInt(rawdatas.get((index * 9) + 6).getStandardScore(), rawdatas.get((index * 9) + 7)
                .getStandardScore(), rawdatas.get((index * 9) + 8).getStandardScore());
        map.put("value", String.valueOf(avg));
        list.add(map);
        rawdatas.get((index * 9 + 6)).setTypeName(getText("chart.vd" + (index * 3 + 2)));
        rawdatas.get((index * 9 + 6)).setLevelName(
                avg >= 9 ? "很高" : (avg >= 7 ? "较高" : (avg >= 5 ? "中等" : (avg >= 3 ? "较低" : "很低"))));

        return list;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Integer getFlamScore() {
        return flamScore;
    }

    public List<Rawdata> getRawdatas() {
        return rawdatas;
    }

    public void setRawdatas(List<Rawdata> rawdatas) {
        this.rawdatas = rawdatas;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public Integer getAdapScore() {
        return adapScore;
    }

    public Integer getDriveScore() {
        return driveScore;
    }

    public Integer getEnsureScore() {
        return ensureScore;
    }

    public Integer getExecuteScore() {
        return executeScore;
    }

    public List<DimensioScore> getDimensioScores() {
        return dimensioScores;
    }

    public String getSpiderCharName() {
        return spiderCharName;
    }

    public String getBarChartName0() {
        return barChartName0;
    }

    public String getBarChartName1() {
        return barChartName1;
    }

    public String getBarChartName2() {
        return barChartName2;
    }

    public String getBarChartName3() {
        return barChartName3;
    }

    public String getBarChartName4() {
        return barChartName4;
    }

    public String getBarChartName5() {
        return barChartName5;
    }

    public String getBarChartName6() {
        return barChartName6;
    }

    public String getBarChartName7() {
        return barChartName7;
    }

    public String getBarChartName8() {
        return barChartName8;
    }

    public String getDimensioDes() {
        return dimensioDes;
    }

    public void setDimensioDes(String dimensioDes) {
        this.dimensioDes = dimensioDes;
    }

}
